package cc.rengu.igas.bsps.core.service.trans;

import cc.rengu.igas.bsps.common.constant.BspsAppParamConstant;
import cc.rengu.igas.bsps.common.dao.BspsDevBindInfoMapper;
import cc.rengu.igas.bsps.common.dao.BspsMchntBindInfoMapper;
import cc.rengu.igas.bsps.common.dao.impl.BspsDevBindInfoMapperImpl;
import cc.rengu.igas.bsps.common.dao.impl.BspsMchntBindInfoMapperImpl;
import cc.rengu.igas.bsps.common.entity.DevBindInfo;
import cc.rengu.igas.bsps.common.entity.MchntBindInfo;
import cc.rengu.igas.bsps.common.enums.BindStatusEnum;
import cc.rengu.igas.bsps.common.enums.DevOprEnum;
import cc.rengu.igas.bsps.common.enums.RespCodeEnum;
import cc.rengu.igas.bsps.core.realize.PublicDealService;
import cc.rengu.igas.bsps.core.realize.impl.PublicDealServiceImpl;
import cc.rengu.igas.bsps.core.service.base.ManageService;
import cc.rengu.igas.bsps.facade.request.VoiceDevBindOrUnBindRequest;
import cc.rengu.igas.bsps.facade.response.VoiceDevBindOrUnBindResponse;
import cc.rengu.oltp.service.common.constant.AppConfigConstant;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.dao.SysParamMapper;
import cc.rengu.oltp.service.common.dao.impl.SysParamMapperImpl;
import cc.rengu.oltp.service.common.entity.SysParam;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.utility.util.*;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author zhangxuran
 * @version 1.0
 * @date 2020/04/03
 * @description:语音设备的绑定解绑，及手机银行语音开关的设置
 */
public class VoiceDevBindOrUnBindService extends ManageService {

    private BspsDevBindInfoMapper bspsDevBindInfoMapper = new BspsDevBindInfoMapperImpl();

    @Override
    protected Object bizBeforeCust() throws Exception {
        VoiceDevBindOrUnBindRequest voiceDevBindOrUnBindRequest = new VoiceDevBindOrUnBindRequest();
        ConvertUtil.convertOutput(voiceDevBindOrUnBindRequest);
        return voiceDevBindOrUnBindRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        VoiceDevBindOrUnBindRequest voiceDevBindOrUnBindRequest = (VoiceDevBindOrUnBindRequest) request;
        VoiceDevBindOrUnBindResponse voiceDevBindOrUnBindResponse = new VoiceDevBindOrUnBindResponse();
        /*获取请求参数:法人行号,用户标识,商户号,操作类型,设备类型,设备唯一标识,设备产品代码,设备其他信息*/
        String instId = voiceDevBindOrUnBindRequest.getHeader().getInstId();
        String userId = voiceDevBindOrUnBindRequest.getUserId();
        String mchntNo = voiceDevBindOrUnBindRequest.getMchntNo();
        String oprType = voiceDevBindOrUnBindRequest.getOprType();
        String devType = voiceDevBindOrUnBindRequest.getDevType();
        String devModel = voiceDevBindOrUnBindRequest.getDevModel();
        String productId = voiceDevBindOrUnBindRequest.getProductId();
        String devUniqueId = voiceDevBindOrUnBindRequest.getDevUniqueId();
        String msgPushFlag = voiceDevBindOrUnBindRequest.getMsgPushFlag();
        if (StringUtil.isEmptyOrNull(userId) || StringUtil.isEmptyOrNull(mchntNo) || StringUtil.isEmptyOrNull(devType)) {
            rglog.error("请求参数校验必填字段失败！");
            throw new BizException(RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespCode(), RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespDesc());
        }

        //查询用户相关信息
        BspsMchntBindInfoMapper bspsMchntBindInfoMapper = new BspsMchntBindInfoMapperImpl();
        MchntBindInfo mchntBindInfo = bspsMchntBindInfoMapper.selectBspsMchntBindInfoListByUserIdAndMchntNo(instId, userId, mchntNo);
        if (null == mchntBindInfo) {
            rglog.error("商户绑定信息查询失败！userId:<{}>,mchntNo:<{}>", userId, mchntNo);
            throw new BizException(RespCodeEnum.USER_MCHNT_BIND_INFO_ERROR.getRespCode(), RespCodeEnum.USER_MCHNT_BIND_INFO_ERROR.getRespDesc());
        }

        /*根据操作类型进行相应操作*/

        DevBindInfo devBindInfo;
        /*绑定操作*/
        if (DevOprEnum.BIND.getDevOprCode().equals(oprType)) {

            if (StringUtil.isEmptyOrNull(productId)) {
                rglog.info("查询默认productId");
                SysParamMapper sysParamMapper = new SysParamMapperImpl();
                SysParam sysParam = sysParamMapper.selectSysParamByPrimaryKey(instId, BspsAppParamConstant.MCHNT_PARAM_TYPE, BspsAppParamConstant.PRODUCT_KEY);
                if (null != sysParam) {
                    productId = sysParam.getParamValue();
                }
                rglog.info("设备productId：" + productId);
            }

            if (StringUtil.isEmptyOrNull(devModel) || StringUtil.isEmptyOrNull(productId)) {
                rglog.error("请求参数校验必填字段失败！");
                throw new BizException(RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespCode(), RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespDesc());
            }

            List<DevBindInfo> devBindInfoList = bspsDevBindInfoMapper.selectBspsDevBindInfoByModelAndProduct(instId, productId, devModel);
            if (CollectionUtils.isEmpty(devBindInfoList)) {
                rglog.error("语音设备信息查询失败！devModel:<{}>,productId:<{}>", devModel, productId);
                throw new BizException(RespCodeEnum.VOICE_INFO_QUERY_ERROR.getRespCode(), RespCodeEnum.VOICE_INFO_QUERY_ERROR.getRespDesc());
            }
            List<DevBindInfo> userBindDev = devBindInfoList.stream().filter(item ->
                    !StringUtil.isEmptyOrNull(item.getBindStatus()) && item.getBindStatus().equals("00")
                            && !StringUtil.isEmptyOrNull(item.getBindMchntNo()) && item.getBindMchntNo().equals(mchntNo)
                            && !StringUtil.isEmptyOrNull(item.getBindUserId()) && item.getBindUserId().equals(userId)).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(userBindDev)) {
                rglog.error("用户已绑定该语言设备！devModel:<{}>,productId:<{}>,userId:<{}>", devModel, productId, userId);
                throw new BizException(RespCodeEnum.VOICE_INFO_QUERY_ERROR.getRespCode(), "用户已绑定该设备");
            }
            devBindInfo = devBindInfoList.get(0);
            if (devBindInfoList.size() == 1) {
                //判断设备是否绑定
                if ("01".equals(devBindInfo.getBindStatus()) && "Y".equals(devBindInfo.getRecordStatus())) {
                    //启用且未绑定，更新数据
                    devBindInfo.setBindUserId(userId);
                    devBindInfo.setBindMchntType(mchntBindInfo.getBindMchntType());
                    devBindInfo.setBindMchntNo(mchntBindInfo.getMchntNo());
                    devBindInfo.setChainMchntNo(mchntBindInfo.getChainMchntNo());
                    devBindInfo.setBindStatus("00");
                    devBindInfo.setBindDate(DateUtil.getCurrentDate());
                    devBindInfo.setBindTime(DateUtil.getCurrentTime());
                    devBindInfo.setLastUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
                    devBindInfo.setLastOprId(userId);
                    int iReturnCode = bspsDevBindInfoMapper.updateVoiceDevInfo(devBindInfo);
                    if (0 != iReturnCode && BspsAppParamConstant.NODATA_CODE != iReturnCode) {
                        rglog.error("语音播报设备绑定失败！userId:<{}>,mchntNo:<{}>,iReturnCode", userId, mchntNo, iReturnCode);
                        throw new BizException(RespCodeEnum.VOICE_BIND_INFO_ERROR.getRespCode(), RespCodeEnum.VOICE_BIND_INFO_ERROR.getRespDesc());
                    }
                } else {
                    //新增语音设备信息数据
                    insertVoiceDevInfo(userId, mchntNo, devModel, productId, mchntBindInfo, devBindInfo);
                }
            } else {
                //新增语音设备信息数据
                insertVoiceDevInfo(userId, mchntNo, devModel, productId, mchntBindInfo, devBindInfo);
            }
        } else if (DevOprEnum.UNBIND.getDevOprCode().equals(oprType)) {
            if (StringUtil.isEmptyOrNull(devUniqueId)) {
                rglog.error("请求参数校验必填字段失败！");
                throw new BizException(RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespCode(), RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespDesc());
            }
            /*解绑操作：1-判断用户是否拥有解绑设备的权限 2-进行解绑操作*/
            /*1-查询设备绑定信息:现有逻辑基于现有业务一个设备只能绑定一个用户，如改成一个设备可以绑定多个收银员时解绑需上送被解绑人ID*/
            /*根据法人行、设备唯一标识和设备类型查询设备绑定收银员ID*/
            devBindInfo = bspsDevBindInfoMapper.selectBspsDevBindInfoByDevUniqueIdAndDevType(instId, devUniqueId, devType, "00");
            if (null == devBindInfo) {
                rglog.error("设备绑定信息查询失败!");
                throw new BizException(RespCodeEnum.GET_DEVBINDINFO_ERROR.getRespCode(), RespCodeEnum.GET_DEVBINDINFO_ERROR.getRespDesc());
            }
            /*校验登录人是否有权限进行操作*/
            PublicDealService publicDealService = new PublicDealServiceImpl();
            boolean authFlag = publicDealService.checkUserOpAuth(instId, mchntNo, userId, devBindInfo.getBindUserId());
            if (!authFlag) {
                rglog.error("当前用户无权操作!");
                throw new BizException(RespCodeEnum.USER_NO_AUTHORITY.getRespCode(), RespCodeEnum.USER_NO_AUTHORITY.getRespDesc());
            }
            /*2-进行设备解绑操作*/
            devBindInfo.setBindStatus(BindStatusEnum.UNBIND.getStatus());
            /*最后操作人信息*/
            devBindInfo.setLastOprId(userId);
            devBindInfo.setLastUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
            int iReturnCode = bspsDevBindInfoMapper.updateBspsDevBindInfoStatusByPrimaryKey(devBindInfo);
            if (0 != iReturnCode && BspsAppParamConstant.NODATA_CODE != iReturnCode) {
                rglog.error("解绑语音设备失败,iReturnCode:<{}>", iReturnCode);
                throw new BizException(RespCodeEnum.UNBIND_DEVBINDINFO_ERROR.getRespCode(), RespCodeEnum.UNBIND_DEVBINDINFO_ERROR.getRespDesc());
            }
        } else if ("02".equals(oprType)) {
            if (StringUtil.isEmptyOrNull(devUniqueId)) {
                rglog.error("请求参数校验必填字段失败！");
                throw new BizException(RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespCode(), RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespDesc());
            }
            /*1-查询设备绑定信息:现有逻辑基于现有业务一个设备只能绑定一个用户，如改成一个设备可以绑定多个收银员时解绑需上送被解绑人ID*/
            /*根据法人行、设备唯一标识和设备类型查询设备绑定收银员ID*/
            devBindInfo = bspsDevBindInfoMapper.selectBspsDevBindInfoByDevUniqueIdAndDevType(instId, devUniqueId, devType, "00");
            if (null == devBindInfo) {
                rglog.error("设备绑定信息查询失败!");
                throw new BizException(RespCodeEnum.GET_DEVBINDINFO_ERROR.getRespCode(), RespCodeEnum.GET_DEVBINDINFO_ERROR.getRespDesc());
            }
            /*校验登录人是否有权限进行操作*/
            PublicDealService mchntService = new PublicDealServiceImpl();
            boolean authFlag = mchntService.checkUserOpAuth(instId, mchntNo, userId, devBindInfo.getBindUserId());
            if (!authFlag) {
                rglog.error("当前用户无权操作!");
                throw new BizException(RespCodeEnum.USER_NO_AUTHORITY.getRespCode(), RespCodeEnum.USER_NO_AUTHORITY.getRespDesc());
            }
            /*2-进行设备开关操作*/
            devBindInfo.setMsgPushFlag(msgPushFlag);
            /*最后操作人信息*/
            devBindInfo.setLastOprId(userId);
            devBindInfo.setLastUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
            int iReturnCode = bspsDevBindInfoMapper.updateBspsDevBindInfoStatusByPrimaryKey(devBindInfo);
            if (0 != iReturnCode && BspsAppParamConstant.NODATA_CODE != iReturnCode) {
                rglog.error("设备开关更新失败,iReturnCode:<{}>", iReturnCode);
                throw new BizException(RespCodeEnum.UNBIND_DEVBINDINFO_ERROR.getRespCode(), RespCodeEnum.UNBIND_DEVBINDINFO_ERROR.getRespDesc());
            }

        }
        /* 拼装响应结果 */
        BizResponse<VoiceDevBindOrUnBindResponse> bizResponse = new BizResponse<>();
        bizResponse.setRspSysId(AppParamConstant.SYS_ID);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setResult(voiceDevBindOrUnBindResponse);
        return bizResponse;
    }

    /**
     * 语音播报设置绑定
     */
    private void insertVoiceDevInfo(String userId, String mchntNo, String devModel, String productId, MchntBindInfo mchntBindInfo, DevBindInfo devBindInfo) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        devBindInfo.setBindDevId(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM));
        devBindInfo.setBindUserId(userId);
        devBindInfo.setBindMchntType(mchntBindInfo.getBindMchntType());
        devBindInfo.setBindMchntNo(mchntBindInfo.getMchntNo());
        devBindInfo.setChainMchntNo(mchntBindInfo.getChainMchntNo());
        devBindInfo.setBindStatus("00");
        devBindInfo.setBindDate(DateUtil.getCurrentDate());
        devBindInfo.setBindTime(DateUtil.getCurrentTime());
        devBindInfo.setCreateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        devBindInfo.setOprId(userId);
        devBindInfo.setBindDevType("02");
        devBindInfo.setRecordStatus("Y");
        devBindInfo.setAuditStatus("02");
        devBindInfo.setBindDevModel(devModel);
        devBindInfo.setBindDevBrand(productId);
        devBindInfo.setMsgPushFlag("Y");
        devBindInfo.setAuditRefuseReason("");
        devBindInfo.setCancelReason("");
        devBindInfo.setStopReason("");

        String dbPoolName = XmlConfigUtil.getXmlConfigCacheKeyValue(AppConfigConstant.DATABASE_CONF_NODE, AppConfigConstant.OLTP_POOL_NAME);
        String corporation = xmlTreeUtil.getXmlTreeStringValue(AppParamConstant.CORPORATION);
        if (null != corporation && !corporation.isEmpty()) {
            String dbPoolCashNode = corporation.trim() + AppParamConstant.DATABASE_CONF_NODE;
            dbPoolName = XmlConfigUtil.getXmlConfigCacheKeyValue(dbPoolCashNode, AppConfigConstant.OLTP_POOL_NAME);
        }
        DbsUtil dbsUtil = new DbsUtil(dbPoolName);
        dbsUtil.dbsBeginTransaction();
        int iReturnCode = bspsDevBindInfoMapper.insertBspsDevBindInfo(devBindInfo);
        if (0 != iReturnCode) {
            dbsUtil.dbsEndTransaction(false);
            rglog.error("语音播报设备绑定失败！userId:<{}>,mchntNo:<{}>,iReturnCode", userId, mchntNo, iReturnCode);
            throw new BizException(RespCodeEnum.VOICE_BIND_INFO_ERROR.getRespCode(), RespCodeEnum.VOICE_BIND_INFO_ERROR.getRespDesc());
        }
        dbsUtil.dbsEndTransaction(true);
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        VoiceDevBindOrUnBindResponse voiceDevBindOrUnBindResponse = (VoiceDevBindOrUnBindResponse) bizResponse.getResult();
        ConvertUtil.convertInput(voiceDevBindOrUnBindResponse);
    }
}